package com.imd.s9.impl;

import com.alibaba.fastjson.JSONObject;
import com.imd.base.BaseResponse;
import com.imd.base.BusinessException;
import com.imd.base.ConditionsVO;
import com.imd.enums.ComparisonSymbol;
import com.imd.s9.entity.CustomActionParam;
import com.imd.s9.entity.TableInfo;
import com.imd.s9.feign.S3Basic;
import com.imd.s9.feign.S5Obj;
import com.imd.s9.feign.S8Bpm;
import com.imd.s9.service.*;
import com.imd.s9.util.FSmsg;
import com.imd.s9.util.InitCriteria;
import com.imd.vo.s3.UserVO;
import com.imd.vo.s5.EntityVO;
import com.imd.vo.s8.ProcessEntityVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author by cuiyulong
 * at 2022/04/08
 * describe：
 */
@Service
@Slf4j
public class CustomImpl implements ICustomService {

    @Resource
    MongoTemplate mongoTemplate;
    @Resource
    S3Basic s3Basic;
    @Resource
    S8Bpm s8Bpm;
    @Resource
    S5Obj s5Obj;

    @Resource
    FinanceService financeService;

    @Resource
    StorageService storageService;

    @Resource
    RoleService roleService;

    @Resource
    PurchaseService purchaseService;

    @Resource
    FeiShuService feiShuService;

    @Resource
    FSmsg fSmsg;

    @Override
    public Object customAction(HttpServletResponse response, CustomActionParam param) throws BusinessException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String method = param.getMethod();
        if (method.startsWith("setParam")) {
            set(param);
            return false;
        } else {
            UserVO userVO = param.getUserVO();
            String objCode = param.getObjCode();
            String entityId = param.getEntityId();
            JSONObject doc = mongoTemplate.findById(new ObjectId(entityId), JSONObject.class, "entity_"+objCode);
            switch (method) {
                case "set":
                    set(param);
                    return false;
                case "syncPublicUser":
                    s3Basic.syncPublicInfo();
                    return false;
                case "launchProcess":
                    ProcessEntityVO vo = new ProcessEntityVO();
                    vo.setFormObjEntityId(param.getEntityId());
                    vo.setProcessDefinitionId(param.getArgs().getOrDefault("processId", "").toString());
                    s8Bpm.startProcess(vo);
                case "projectCost":
                    //取消任务
                    financeService.createProjectCost(doc.getString("tenantId"),doc.getString("项目名称"));
                    return false;
                case "exec":
                    storageService.inOutRoom(objCode,doc);
                    return false;
                case "sendMsg":
                    JSONObject object1 = fSmsg.field(true,"**申请人:**\n"+doc.getString("createName"));
                    JSONObject object2 = fSmsg.field(true,"**单号:**\n"+doc.getString("单据编号"));
                    JSONObject object3 = fSmsg.field(false,"**创建时间:**\n"+sdf.format(doc.getDate("createTime")));
                    UserVO user = roleService.getDepartmentLeader(doc.getString("createId"),doc.getString("tenantId"));
                    List<UserVO> list = new ArrayList<>();
                    list.add(user);
                    feiShuService.testFSMsg(list,param.getArgs().get("title").toString(),object1,object2,object3);
                    return false;
                case "examine":
                    Boolean bl = ObjectUtils.isEmpty(doc.get("订单状态"))?false:doc.getBoolean("订单状态");
                    if(bl){
                        throw new BusinessException("当前订单已下发");
                    }
                    Update up = new Update();
                    up.set("订单状态",true);
                    Query query = new Query();
                    query.addCriteria(Criteria.where("_id").is(new ObjectId(entityId)));
                    mongoTemplate.updateFirst(query,up,"entity_"+objCode);
                    doc.remove("_id");
                    HashMap map1 = new HashMap(doc);
                    mongoTemplate.save(map1, TableInfo.technology);
                    return false;
                case "incomeAudit":
                    Update uu = new Update();
                    uu.set("订单状态",true);
                    Query qq = new Query();
                    qq.addCriteria(Criteria.where("_id").is(new ObjectId(entityId)));
                    mongoTemplate.updateFirst(qq,uu,"entity_"+objCode);

                    JSONObject ob1 = fSmsg.field(true,"**申请人:**\n"+doc.getString("createName"));
                    JSONObject ob2 = fSmsg.field(true,"**单号:**\n"+doc.getString("单据编号"));
                    JSONObject ob3 = fSmsg.field(false,"**创建时间:**\n"+sdf.format(doc.getDate("createTime")));
                    String roleNames = param.getArgs().get("role").toString();
                    String[] roleName = roleNames.split(",");
                    List<UserVO> users = new ArrayList<>();
                    for(String s:roleName){
                        List<UserVO> sales = roleService.roleGetUser(s,doc.getString("tenantId"));
                        if(sales==null||sales.isEmpty()){
                            continue;
                        }
                        users.addAll(sales);
                    }
                    feiShuService.testFSMsg(users,param.getArgs().get("title").toString(),ob1,ob2, ob3);
                    return false;
                case "createOrder":
                    purchaseService.createOrder(doc,userVO);
                    return false;
                case "createOrder1":
                    purchaseService.createOrder1(doc,userVO);
                    return false;
                case "pushStorage":
                    purchaseService.pushStorage(doc,userVO);
                    return false;
                case "inRoom":
                    Query query1 = new Query();
                    query1.addCriteria(Criteria.where("_id").is(new ObjectId(entityId)));
                    Document checkReport = mongoTemplate.findOne(query1,Document.class,TableInfo.checkReport);
                    List<Document> list1 = checkReport.getList("检验明细", Document.class);
                    String incomeOrder = checkReport.getString("来料单号");

                    Query isInRoom = new Query(Criteria.where("tenantId").is(doc.getString("tenantId"))
                            .and("isDelete").is(0).and("来料单号").is(incomeOrder)
                            .and("入库状态").is(true)
                    );
                   if(mongoTemplate.exists(isInRoom,TableInfo.checkData)){
                       throw new BusinessException("来料单已被执行");
                   }
                    for(Document d:list1){
                        String material = d.get("物料").toString();
                        Query query2 = new Query(Criteria.where("tenantId").is(doc.getString("tenantId"))
                                .and("isDelete").is(0).and("物料编码").is(material));
                        Document materialDoc = mongoTemplate.findOne(query2,Document.class,TableInfo.materialMana);
                        if(materialDoc==null){
                            throw new BusinessException("不存在物料["+material+"]");
                        }
                        BigDecimal totalNum = new BigDecimal(d.get("批次总量").toString());
                        BigDecimal passNum = new BigDecimal(d.get("合格数").toString());
                        BigDecimal nuPassNUm = new BigDecimal(d.get("不合格数").toString());
                        String checkWay = d.get("抽检方式").toString();
                        if("抽检".equals(checkWay)){
                            BigDecimal passRate = passNum.divide(passNum.add(nuPassNUm)).setScale(2,BigDecimal.ROUND_HALF_UP)
                                    .multiply(new BigDecimal(100));
                            if(passRate.compareTo(new BigDecimal(materialDoc.getDouble("合格率")))>=0){
                                BigDecimal count = new BigDecimal(materialDoc.get("数量").toString()).add(totalNum);
                                Update update = new Update();
                                update.set("数量",count.doubleValue());
                                mongoTemplate.updateFirst(query2,update,TableInfo.materialMana);
                            }
                        }else {
                            BigDecimal count = new BigDecimal(materialDoc.getDouble("数量")).add(passNum);
                            Update update = new Update();
                            update.set("数量",count.doubleValue());
                            mongoTemplate.updateFirst(query2,update,TableInfo.materialMana);
                        }
                        Query query3 = new Query(Criteria.where("tenantId").is(doc.getString("tenantId"))
                                .and("isDelete").is(0).and("物料").is(material)
                                .and("来料单号").is(incomeOrder));
                        Update update = new Update();
                        update.set("入库状态",true);
                        mongoTemplate.updateMulti(query3,update,TableInfo.checkData);
                    }
                    return false;
                default:
            }
        }
        return false;
    }

    /**
     * 对象自定义属性行为
     *
     * @param response
     * @param param
     * @throws BusinessException
     */
    @Override
    public Object customOp(HttpServletResponse response, CustomActionParam param) throws BusinessException {


        return null;
    }


    /**
     * 通用修改属性行为
     *
     * @param param
     * @throws BusinessException
     */
    private void set(CustomActionParam param) throws BusinessException {
        Map<String, Object> args = param.getArgs();
        if (ObjectUtils.isEmpty(args)) return;
        BaseResponse br = null;
        String entityId = param.getEntityId();
        List<String> entityIds = param.getEntityIds();
        if(!StringUtils.isEmpty(entityId)){
             br = s5Obj.updateEntity(args, param.getObjCode(), entityId);
        }else if(!ObjectUtils.isEmpty(entityIds)){
            EntityVO entity = new EntityVO();
            entity.setEntity(args);
            List<ConditionsVO.Condition> conds = new ArrayList<>();
            ConditionsVO.Condition cond = new ConditionsVO.Condition();
            conds.add(cond);
            entity.setConditions(conds);
            cond.setKey("_id").setSymbol(ComparisonSymbol.in.name()).setValue(entityIds);
            br = s5Obj.updateEntitys(entity, param.getObjCode());
        }
        if (br!=null&&!br.isOk()) throw new BusinessException(br.getCode(), br.getDesc());
    }

}









